package com.binguo.api.service;

import com.binguo.common.util.LoggerUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class GroovyService  implements ApplicationContextAware, InitializingBean {

    @Value("${groovy.dir}")
    private String dir;

    private ApplicationContext context; 		// spring context

    /**
     * 加载特定目录脚本文件
     *
     * @return
     * @throws BeansException
     * @throws FileNotFoundException
     */
    public List<String> reload() throws BeansException, FileNotFoundException {
        // spring的beanfactory,用来注册新bean
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();

        // spring groovy加载器的参数
        final String refreshCheckDelay = "org.springframework.scripting.support.ScriptFactoryPostProcessor.refreshCheckDelay";
        final String language = "org.springframework.scripting.support.ScriptFactoryPostProcessor.language";

        // 访问路径下所有groovy文件
        Resource[] groovyDoc = null;
        try {
            groovyDoc = context.getResources(dir + "/*.groovy");
        } catch (IOException e) {
            throw new FileNotFoundException("groovy路径配置错误 - " + dir);
        }

        List<String> result = new ArrayList<>();

        // 遍历文件
        for (Resource file : groovyDoc) {
            // 文件名
            String filename = file.getFilename();

            // 注册bean的名称,取文件名去除扩展名
            String beanname = filename.replace(".groovy", "");
            // 对于未注册的bean,进行注册
            if(!context.containsBean(beanname)) {
                LoggerUtil.sys.debug("发现新Groovy定义,加载脚本文件 [{}]",file);
                // spring bean定义
                GenericBeanDefinition bd = new GenericBeanDefinition();
                // spring groovy脚本工厂
                bd.setBeanClassName("org.springframework.scripting.groovy.GroovyScriptFactory");
                // 刷新时间
                bd.setAttribute(refreshCheckDelay, 5000);
                // 语言脚本
                bd.setAttribute(language, "groovy");
                // 文件目录  接收spring resource格式
                try {
                    bd.getConstructorArgumentValues().addIndexedArgumentValue(0, file.getURI().toString());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 注册到spring容器
                beanFactory.registerBeanDefinition(beanname, bd);

                result.add(file.toString());
            }
        }

        return result;
    }

    public ApplicationContext getContext() {
        return context;
    }

    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        reload();
    }
}
